#pragma once

#include <iostream>
#include <memory>
#include <functional>
#include <sys/wait.h>
#include "Socket.hpp"

namespace TcpServerModule
{
    using namespace SocketModule;
    using tcphander_t = std::function<bool(SockPtr, InetAddr)>;

    class TcpServer
    {
    public:
        TcpServer(int port):_port(port), _listensockp(std::make_unique<TcpSocket>()), _running(false)
        {
        }
        void InitServer(tcphander_t hander)
        {
            _hander = hander;
            _listensockp->BuildTcpSocketMethod(_port);
        }
        void Loop()
        {
            _running = true;
            while(1)
            {
                //1Accept
                InetAddr clientaddr;
                auto sockfd = _listensockp->Accepter(&clientaddr);
                //2 IO处理
                LOG(LogLevel::DEBUG)<<"get a new client, info is"<<clientaddr.Addr();
                //多进程版本
                pid_t id = fork();
                if(id==0)
                {
                    _listensockp->Close();
                    if(fork()>0)    exit(0);
                    _hander(sockfd, clientaddr);
                }
                sockfd->Close();
                waitpid(id, nullptr, 0);
            }
            _running = false;
        }
        ~TcpServer()
        {
            _listensockp->Close();
        }

    private:
        // 要有ListenSocket
        std::unique_ptr<Socket> _listensockp;
        bool _running;
        tcphander_t _hander;
        uint16_t _port;
    };
}